package world.unit;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.concurrent.LinkedBlockingQueue;

import util.Boundable;
import world.World;
import world.action.Action;
import world.unit.weapon.Weapon;

/**
 * represents the basic unit class
 * <br><br>
 * note: although each unit will have a specific owner, currently
 * any object with a reference to the unit can access any method of
 * the unit, clearly this can be exploited in game; to prevent this
 * permissions should be set up (see {@link java.security.Permissions})
 * @author jack
 *
 */
public class Unit implements Boundable
{
	private double[] l; //unit location
	private int owner;
	private double movement; //the move speed of the unit
	private double size = 20; //the length of each dimension of the unit
	private double[] dim = new double[]{size, size}; //created like this to avoid creating new double[] objects for each getDimension call
	private LinkedBlockingQueue<Action> actions = new LinkedBlockingQueue<Action>();
	private Weapon w; //null counts as no weapon
	
	/**
	 * a basic constructor for creating a simple test unit
	 * @param l
	 * @param owner
	 */
	public Unit(double[] l, int owner)
	{
		
	}
	public void setLocation(double[] l)
	{
		this.l = l;
	}
	public double getMovement()
	{
		return movement;
	}
	public void updateUnit(double tdiff, World world)
	{
		updateActions(tdiff, world);
		if(w != null)
		{
			w.updateWeapon(world);
		}
	}
	private void updateActions(double tdiff, World w)
	{
		if(actions.size() > 0)
		{
			double remaining = actions.peek().executeAction(tdiff);
			if(actions.peek().isDone())
			{
				actions.poll();
				if(remaining > 0)
					updateActions(remaining, w);
			}
		}
	}
	/**
	 * sets the action to be executed by the unit upon update,
	 * this has the effect of removing all queued actions by the unit
	 * @param a
	 */
	public void setAction(Action a)
	{
		actions.clear();
		actions.add(a);
	}
	/**
	 * queues an action to be executed, actions are executed in the order
	 * they are queued
	 * @param a
	 */
	public void queueAction(Action a)
	{
		actions.add(a);
	}
	public void drawUnit(Graphics2D g)
	{
		g.setColor(Color.red);
		g.fillRect((int)l[0], (int)l[1], (int)dim[0], (int)dim[1]);
	}
	/**
	 * sets the size of the unit, this method should be used in place of directly
	 * modifying the size and dim objects
	 * @param size
	 */
	private void setSize(double size)
	{
		this.size = size;
		dim = new double[]{size, size};
	}
	public double[] getLocation()
	{
		return l;
	}
	public double[] getDimensions()
	{
		return dim;
	}
}
